program Project1;

{$APPTYPE CONSOLE}
{$RESOURCE *.res}

uses
  Windows, Winsock, IniFiles;

const
  request1 = 'GET / HTTP/1.1'#10+
        'Accept: text/html, */*'#10+
        'Accept-Language: en'#10+
        'Accept-Encoding: gzip, deflate'#10+
        'User-Agent: Mozilla/10.0'#10+
        'Host: example.com'#10+
        'Connection: Keep-Alive'#10+
        'Pragma: no-cache'#10+
        'Accept-Language: en'#10#10;

type
  TSOCKS4_REQUEST = record
    ucVersion : byte;
    ucCommand : byte;
    wDestPort : word;
    dwDestIp  : dword;
  end;

var
  srvhost:ansistring;
  srvport:integer;
  remhost:ansistring;
  remport:integer;

  WD:TWSAData;
  S:TSocket;
  A:sockaddr_in;
  R:TSOCKS4_REQUEST;
  C:array [0..1024] of AnsiChar;
  I:Integer;
  Ini:TIniFile;

procedure die(obituary:string);
begin
  WriteLn(obituary);
  CloseSocket(S);
  WSACleanup;
  ReadLn(obituary);
  ExitProcess(0);
end;

procedure log(msg:string);
begin
  WriteLn(msg);
end;

begin
  Ini:=TIniFile.Create(ParamStr(0)+'.ini');
  srvhost:=Ini.ReadString('settings','srvhost','127.0.0.1');
  srvport:=Ini.ReadInteger('settings','srvport',606);
  remhost:=Ini.ReadString('settings','remhost','127.0.0.1');
  remport:=Ini.ReadInteger('settings','remport',80);
  Ini.Free;
  WSAStartup($101, WD);
  log('---#startup');
  S:=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  A.sin_family:=PF_INET;
  A.sin_port:=htons(srvport);
  A.sin_addr.S_addr:=inet_addr(PAnsiChar(srvhost));
  FillChar(A.sin_zero,sizeof(A.sin_zero),0);
  if connect(S,A,sizeof(A))<>0 then die('---##connect');
  log('---#connected');
  //Construct s4 header
  R.ucVersion:=4;
  R.ucCommand:=1;
  R.wDestPort:=htons(remport);
  R.dwDestIp:=inet_addr(PAnsiChar(remhost));
  //Send header to connect
  if send(S,R,sizeof(R),0)=0 then
    die('---##zero.s4hdr');
  //If not 90 then we give a shit, wtfk?
  recv(S,R,sizeof(R),0);
  if R.ucCommand<>90 then
    die('---##wtfk.s4con');

  //Transfers.. beginning of the end
  log('---#send');
  lstrcpyA(C,request1);
  log(C);
  if send(S,C,lstrlenA(C),0)=0 then
    die('---##zero.send');
             
  log('---#recv');
  repeat
    FillChar(C,sizeof(C),0);
    I:=recv(S,C,sizeof(C),0);
    if I>0 then log(C) else Break;
    Beep(100,50)
  until false;
  //Destruction completed
  die('---#session.end');
end.
